package Serveur;

import java.util.ArrayList;
import java.util.HashMap;

import Both.*;

/**
 * Cette classe permet de creer des Noeuds qui serviront a effectuer des
 * recherches pour aller d'une ville A a� une ville B utilisant une succession
 * de transport
 * 
 * @author Jeremie
 * 
 */

public class Noeud {
    // la ville du noeud chaque noeud est caracterise par une seule ville
    private Ville villeCourante;
    // la liste des destinations ou l'on peut se rendre en un seul trajet a
    // partir de la villeCourante
    private ArrayList<Noeud> listNoeud;
    // une HashMap qui contient toutes les villes d'origine qui nous ont permis
    // de rejoindre la villeCourante ainsi
    // que le moyen de transport utilise
    private HashMap<Noeud, Trajet> listParent;
    // le Noeud parent sert pour retracer le chemin
    private Noeud parent;
    // le temps total mis pour arriver a la villeCourante
    private int time;
    // le nombre total de deplacements utilises
    private int nbDeplacementActuel;
    private int nbDeplacementFinal;
    private int nbDeplacementPrevu;

    /**
     * Constructeur normal
     * 
     * @param ville
     *            v
     * @param trajet
     *            pour arrive a la ville v
     * @param parent
     *            : ville d'ou on vient
     */

    public Noeud(Ville v, Trajet t, Noeud parent) {
        this.villeCourante = v;
        this.listNoeud = new ArrayList<Noeud>();
        this.listParent = new HashMap<Noeud, Trajet>();
        if (parent != null) {
            parent.ajouterNoeud(this, t);
        }
        if (t != null) {
            time = t.getTime();
        } else {
            time = 0;
        }
    }

    public Noeud getParent() {
        return parent;
    }

    public int getTime() {
        return time;
    }

    public int getNbreDeplacementActuel() {
        return nbDeplacementActuel;
    }

    public void setNbreDeplacementActuel(int n) {
        nbDeplacementActuel = n + 1;
    }

    public int getNbreDeplacementFinal() {
        return nbDeplacementFinal;
    }

    public void setNbreDeplacementFinal() {
        nbDeplacementFinal = nbDeplacementActuel + nbDeplacementPrevu;
    }

    public int getNbreDeplacementPrevu() {
        return nbDeplacementPrevu;
    }

    public void setParent(Noeud p) {
        parent = p;
    }

    public void setTime(int t) {
        time += t;
    }

    public void setTrajet(Noeud noeudParent, Trajet t) {
        listParent.put(noeudParent, t);
    }

    public void ajouterNoeud(Noeud noeudFils, Trajet t) {
        listNoeud.add(noeudFils);
        noeudFils.setTrajet(this, t);
    }

    public Ville getVille() {
        return villeCourante;
    }

    public Trajet getTrajet(Noeud n) {
        return listParent.get(n);
    }

    public ArrayList<Noeud> getListNoeud() {
        return listNoeud;
    }

    /**
     * Rechercher si une ville est presente dans le resau
     * 
     * @param noeudCourant
     *            : Noeud a partir du quel on veut effectuer la recherche
     * @param ville
     *            v : ville recherche
     * @return boolean
     */

    public boolean villePresente(Noeud noeudCourant, Ville v) {
        // on parcourt la liste des destinations du noeudCourant recursivement
        // jusqu'a trouvé la ville cherche sauf si innexistante
        if (noeudCourant.getVille().equals(v))
            return true;
        for (int i = 0; i < noeudCourant.getListNoeud().size(); i++) {
            return villePresente(noeudCourant.getListNoeud().get(i), v);
        }
        return false;
    }

    /**
     * Rechercher le nbre de deplacement pour atteindre la ville v
     * 
     * @param noeudCourant
     *            : Noeud a partir du quel on veut effectuer la recherche
     * @param ville
     *            v : ville recherche
     * 
     */

    public void nbreDeplacementAFaire(Noeud noeudCourant, Ville v, int n) {
        // on parcourt la liste des destinations du noeudCourant recursivement
        // jusqu'a trouvé la ville cherche sauf si innexistante
        nbDeplacementPrevu = n;
        if (!noeudCourant.getVille().equals(v)) {
            for (int i = 0; i < noeudCourant.getListNoeud().size(); i++) {
                nbreDeplacementAFaire(noeudCourant.getListNoeud().get(i), v,
                        nbDeplacementPrevu);
            }
        }
    }

    /**
     * Rechercher si une ville est atteignable avec les contrainte de temps
     * 
     * @param noeudCourant
     *            : Noeud a partir du quel on veut effectuer la recherche
     * @param ville
     *            v : ville recherche
     * @return boolean
     * 
     * 
     *         public boolean cheminUtilisable(Noeud noeudCourant, Ville v, int
     *         date) { ArrayList<Noeud> maList = noeudCourant.getListNoeud(); //
     *         on parcourt la liste des destinations du noeudCourant
     *         recursivement // jusqu'a trouvé la ville cherche sauf si
     *         innexistante for (int i = 0; i <
     *         noeudCourant.getListNoeud().size(); i++) { //verifie si la on
     *         peut prendre le trajet (si la date de depart du trajet n'est pas
     *         inferrieur //a la date ou l'on arrive a la ville du noeudcourant
     *         if(noeudCourant.getListNoeud().get(i).getTrajet(this) == null){
     *         System.out.println("qfdkosqdfjiojfiqjfiqjfiqspjfjqsigjqpo"); }
     *         if(
     *         (noeudCourant.getListNoeud().get(i).getTrajet(this.getParent())
     *         .getTimeDepart()) > date){
     *         System.out.println("------------------------------");
     *         System.out.println
     *         (noeudCourant.getListNoeud().get(i).getTrajet(this
     *         ).getTimeDepart());
     * 
     *         if (noeudCourant.getListNoeud().get(i).getVille().equals(v)) {
     *         return true; } else { if
     *         (ListTrajetUtilisable(noeudCourant.getListNoeud().get(i), v,
     *         noeudCourant
     *         .getListNoeud().get(i).getTrajet(this).getTimeDarrive())) {
     *         return true; } } } else{ System.out.println("sdfqkjfkqfj"); //on
     *         retire le Noeud que l'on ne peut pas atteindre car le trajet ne
     *         peut etre pris pour cause de //date non correspondante
     *         noeudCourant.getListNoeud().remove(i); } } return false; }
     */

    /**
     * Recherche un Noeud avec pour ville la ville v
     * 
     * @param noeudCourant
     *            : Noeud a partir du quel on veut effectuer la recherche
     * @param ville
     *            v : ville recherche
     * @return Noeud
     */

    public static Noeud getNoeud(Noeud noeudCourant, Ville v) {
        Noeud temp;
        // on parcourt la liste des destinations du noeudCourant jusqu'a trouver
        // le noeud de la ville v
        for (int i = 0; i < noeudCourant.getListNoeud().size(); i++) {
            temp = noeudCourant.getListNoeud().get(i);
            if (temp.getVille().equals(v)) {
                return temp;
            } else {
                return getNoeud(noeudCourant.getListNoeud().get(i), v);
            }
        }
        return null;
    }

}
